package com.suxin.algorithm.queue;

/**
 * @author Tang
 * @classname ArrayQueue
 * @description [ 循环队列-数组 ]
 * @date 2022/4/13 23:04
 */
public class CycleArrayQueue {

    /**
     * 数组最大存储的个数
     */
    private int maxSize;

    /**
     * 队头
     */
    private int front;

    /**
     * 队尾
     */
    private int rear;

    /**
     * 数据
     */
    private int[] array;

    public CycleArrayQueue(int arrMaxSize) {
        this.maxSize = arrMaxSize;
        array = new int[arrMaxSize];
        front = 0;
        rear = 0;
    }

    /**
     * add
     * @param i
     */
    public void addQueue(int i) {
        if (full()) {
            System.out.println("queue full !");
            return;
        }
        array[rear] = i;
        rear = (rear + 1) % maxSize;
    }

    /**
     * get head
     * @return
     */
    public int getQueue() {
        if (isEmpty()) {
            throw new RuntimeException("empty queue!");
        }
        int value = array[front];
        front = (front + 1) % maxSize;
        return value;
    }

    /**
     * 遍历队列
     */
    public void showQueue() {
        if (isEmpty()) {
            return;
        }
        //从front首位置开始，加有效长度后结束
        for (int i = front; i < front + size(); i++) {
            System.out.printf("arr[%d] = %d\n", i% maxSize, array[i % maxSize]);
        }
    }

    /**
     * 有效元素个数
     * @return
     */
    public int size() {
        return (rear - front + maxSize) % maxSize;
    }

    private boolean isEmpty() {
        /**
         * 队头 == 队尾
         */
        return front == rear;
    }

    private boolean full() {
        // 队尾 + 1 % 数组大小 = 队头
        return (rear + 1) % maxSize == front;
    }

    public static void main(String[] args) {
        CycleArrayQueue cycleArrayQueue = new CycleArrayQueue(5);
        cycleArrayQueue.addQueue(1);
        cycleArrayQueue.addQueue(2);
        cycleArrayQueue.addQueue(3);

        System.out.println("出队-->" + cycleArrayQueue.getQueue());

        cycleArrayQueue.addQueue(4);

        cycleArrayQueue.addQueue(5);

        cycleArrayQueue.showQueue();
    }

}